﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using NLog;

namespace Labthink.PCSoft.UniversalHost4.Utility
{
    /// <summary>
    /// 语言
    /// ZH（中），EN（英），JA（日），KO（韩），ES（西），FR（法），DE（德），AR（阿拉伯），RU（俄）
    /// </summary>
    public class LanguageTool
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        private static readonly string Config = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase) + "Config//AppConfig.ini";
       
        /// <summary>
        /// 默认语言
        /// 读取Wince的默认语言
        /// </summary>
        private static readonly Dictionary<string, string> Lans = new Dictionary<string, string>();
       
        /// <summary>
        /// 扩展语言
        /// 和上位机语言一致
        /// </summary>
        private static readonly Dictionary<string, string> ExpendLans = new Dictionary<string, string>();
        private static readonly List<string> LanTypes = new List<string> { "ZH", "EN", "JA", "KO", "ES", "FR", "DE", "AR", "RU" };

        // ReSharper disable once UnusedAutoPropertyAccessor.Local
        public static string LanguageId { get; private set; }
        public static string ExpendLanguageId;

        static LanguageTool()
        {
            //var l = IniHelper.GetIni(Config, "base", "lan", "");
            //if (l != "")
            //{
            //    LanguageId = l.ToUpper();
            //    ExpendLanguageId = LanguageId;
            //    return;
            //}
            var lan = GetOsCultureName();
            OperatingSystem os = Environment.OSVersion;
            Logger.Debug("操作系统: {0}({1}), 语言: {2}", os.Platform, os.Version, lan);

            LanguageId = lan.Substring(0, 2).ToUpper();
            ExpendLanguageId = LanguageId;
            if (!LanTypes.Contains(LanguageId)) LanguageId = "EN";
        }

        /// <summary>
        /// 设置语言
        /// </summary>
        /// <param name="key"></param>
        /// <param name="lan"></param>
        /// <param name="lid"></param>
        /// <returns></returns>
        public static int SetLanguage(string key, string lan, string lid)
        {
            var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase), "Localization//Languages");
            var file = $"{path}.{lid}";
            if (!File.Exists(file))
            {
                file = $"{path}.{lid}.txt";
            }

            if (!File.Exists(file))
            {
                var exp = new FileNotFoundException("file not exists");
                Logger.Error("语言文件没有找到", exp);
                return -1;
            }

            try
            {
                var xml = XDocument.Load(file);
                var names = from el in xml.Descendants("Messages").Elements()
                            where (string)el.Attribute("name") == key
                            select el;
                names.First().Value = lan;
                xml.Save(file);
                if (lid.ToUpper() == LanguageId) Lans[key] = lan;
                else ExpendLans[key] = lan;
            }
            catch (Exception e)
            {
                Logger.Error("修改{0}语言失败", e, key);
                return -1;
            }

            return 0;
        }

        /// <summary>
        /// 加载默认语言
        /// </summary>
        public static void LoadLanguages()
        {
            if (Lans.Count > 0) return;
            Logger.Debug("加载语言");
            var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase), "Localization//Languages");
            var file = $"{path}.{LanguageId}";
            //检查是否添加txt后缀名
            if (!File.Exists(file))
            {
                file = $"{path}.{LanguageId}.txt";
            }

            if (!File.Exists(file))
            {
                var exp = new FileNotFoundException("file not exists");
                Logger.Error("语言文件没有找到", exp);
                throw exp;
            }

            //读取xml中的语言信息
            var xml = XDocument.Load(file);
            var elements = xml.Descendants("Messages").Elements();
            foreach (var e in elements)
            {
                var xAttribute = e.Attribute("name");
                if (xAttribute != null)
                {
                    var key = xAttribute.Value;
                    var value = e.Value;
                    if (!Lans.ContainsKey(key))
                    {

                        Lans.Add(key, value.Trim());
                    }
                }
            }

            Logger.Debug("加载语言完成");
        }

        /// <summary>
        /// 加载扩展语言
        /// </summary>
        /// <param name="lanId">语言Id</param>
        public static void LoadExpendLanguages(string lanId)
        {
            ExpendLanguageId = lanId.ToUpper();
            Logger.Debug("扩展语言：{0}", lanId);
            if (ExpendLanguageId.Equals(LanguageId))
            {
                Logger.Debug("扩展语言和默认语言一致，不用重新加载");
                return;
            }

            if (ExpendLans.Count > 0)
            {
                Logger.Debug("扩展语言已经加载过，不用重新加载");
                return;
            }

            Logger.Debug("开始加载扩展语言");
            var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase), "Localization//Languages");
            var file = $"{path}.{ExpendLanguageId}";

            //检查是否添加txt后缀名
            if (!File.Exists(file))
            {
                file = $"{path}.{ExpendLanguageId}.txt";
            }

            if (!File.Exists(file))
            {
                var exp = new FileNotFoundException("file not exists");
                Logger.Error("扩展语言文件没有找到,尝试加载英语", exp);
                if (LanguageId == "EN") return;
                ExpendLanguageId = "EN";
                file = $"{path}.{ExpendLanguageId}";
                if (!File.Exists(file))
                {
                    file = $"{path}.{ExpendLanguageId}.txt";
                }

                if (!File.Exists(file))
                {
                    Logger.Error("扩展语言加载失败，使用默认语言", exp);
                    ExpendLanguageId = LanguageId;
                    return;
                }
            }

            //读取xml中的语言信息
            var xml = XDocument.Load(file);
            var elements = xml.Descendants("Messages").Elements();
            foreach (var e in elements)
            {
                var xAttribute = e.Attribute("name");
                if (xAttribute != null)
                {
                    var key = xAttribute.Value;
                    var value = e.Value;
                    if (!ExpendLans.ContainsKey(key))
                    {
                        ExpendLans.Add(key, value.Trim());
                    }
                }
            }

            Logger.Debug("加载扩展语言完成");
        }

        /// <summary>
        /// 获取语言
        /// </summary>
        /// <param name="key">语言编号</param>
        /// <returns></returns>
        public static string GetLanguage(string key)
        {
            if (!Lans.ContainsKey(key))
            {
                if (!string.IsNullOrEmpty(key))
                {
                    Logger.Error("默认语言包中没有找到编号是 \"{0}\" 的语言", key);
                }

                return key;
            }

            return Lans[key];
        }

        /// <summary>
        /// 获取扩展语言
        /// </summary>
        /// <param name="key">语言编号</param>
        /// <returns></returns>
        public static string GetExpendLanguage(string key)
        {
            if (ExpendLanguageId.Equals(LanguageId)) return GetLanguage(key);

            if (!ExpendLans.ContainsKey(key))
            {
                if (!string.IsNullOrEmpty(key))
                {
                    Logger.Error("扩展语言包中没有找到编号是 \"{0}\" 的语言，返回默认语言", key);
                }

                return GetLanguage(key);
            }

            return ExpendLans[key];
        }

        /// <summary>
        /// 获取全部设备名称
        /// </summary>
        /// <param name="lid"></param>
        /// <returns></returns>
        public static List<string> GetDeviceNames(string lid)
        {
            if (string.IsNullOrEmpty(lid)) lid = LanguageId;
            var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase), "Localization//Languages");
            var file = $"{path}.{lid}";

            //检查是否添加txt后缀名
            if (!File.Exists(file))
            {
                file = $"{path}.{ExpendLanguageId}.txt";
            }

            if (!File.Exists(file))
            {
                ExpendLanguageId = "EN";
                file = $"{path}.{ExpendLanguageId}";
                if (!File.Exists(file))
                {
                    file = $"{path}.{ExpendLanguageId}.txt";
                }

                if (!File.Exists(file))
                {
                    Logger.Error("扩展语言加载失败，使用默认语言");
                    ExpendLanguageId = LanguageId;
                    return null;
                }
            }

            var xml = XDocument.Load(file);
            var elements = xml.Descendants("Messages").Elements();
            var names = new List<string>();
            foreach (var e in elements)
            {
                var xAttribute = e.Attribute("name");
                if (xAttribute != null)
                {
                    var key = xAttribute.Value;
                    var value = e.Value;
                    if (key.StartsWith("Name") && key != "Name")
                    {
                        names.Add(value);
                    }
                }
            }

            return names;
        }

        /// <summary>
        /// 根据语言编号获取语言
        /// </summary>
        /// <param name="key"></param>
        /// <param name="lid"></param>
        /// <param name="objects"></param>
        /// <returns></returns>
        public static string GetLanguage(string key, string lid, params object[] objects)
        {
            try
            {
                if (string.IsNullOrEmpty(lid)) lid = LanguageId;
                if (lid.Equals(LanguageId))
                {
                    return GetLanguage(key, objects);
                }

                return GetExpendLanguage(key, objects);
            }
            catch (Exception e)
            {
                return "";
            }
        }

        /// <summary>
        /// 获取语言
        /// </summary>
        /// <param name="key">语言编号</param>
        /// <param name="objects"></param>
        /// <returns></returns>
        private static string GetLanguage(string key, params object[] objects)
        {
            if (!Lans.ContainsKey(key))
            {
                Logger.Error("语言包中没有找到编号是{0}的语言", key);
                return key;
            }

            try
            {
                if (objects != null && objects.Length > 0)
                {
                    return string.Format(Lans[key], objects);
                }
            }
            catch (Exception e)
            {
                Logger.Error(e);
                return key;
            }

            return Lans[key];
        }

        /// <summary>
        /// 获取扩展语言
        /// </summary>
        /// <param name="key">语言编号</param>
        /// <param name="objects"></param>
        /// <returns></returns>
        public static string GetExpendLanguage(string key, params object[] objects)
        {
            if (ExpendLanguageId.Equals(LanguageId)) return GetLanguage(key, objects);
            if (!ExpendLans.ContainsKey(key))
            {
                Logger.Error("扩展语言包中没有找到编号是{0}的语言", key);
                return key;
            }
            try
            {
                if (objects != null && objects.Length > 0)
                {
                    return string.Format(ExpendLans[key], objects);
                }
            }
            catch (Exception e)
            {
                Logger.Error(e);
                return key;
            }

            return ExpendLans[key];
        }

        private static string GetOsCultureName()
        {
            CultureInfo ci = CultureInfo.CurrentUICulture;
            return ci.Name;
        }
    }
}
